package com.etcn.manager.controller;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.surfnet.oaaas.model.Client;
import org.surfnet.oaaas.model.ResourceServer;

import com.etcn.manager.model.ClientPage;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
@Controller
@RequestMapping("/common")
public class BaseController {
	protected static final String ACCESS_TOKEN = "f44a2053-cb03-46bd-80ab-190289d8f5b9";
	protected int defaultServletPort = 8080;
	protected final String USERTYPE_ADMIN="admin";
	protected final String USERTYPE_DEV="developer";
	protected ClientConfig config = null;
	public BaseController(){
		config =new DefaultClientConfig();
		config.getClasses().add(JacksonJsonProvider.class); 
	}
	
	/**
	 * get one resource server's info
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping("/resServer/getOneResServer")
	public String getOneResourceServer(ModelMap model,String id,HttpServletRequest request,Integer resType,Integer pageNow){
		
		WebResource webResource = com.sun.jersey.api.client.Client.create(config).resource(baseUrl()).path("admin").path("resourceServer");
		
		ResourceServer resServer = webResource.path(id).header("Authorization", authorizationBearer(ACCESS_TOKEN)).get(
				new GenericType<ResourceServer>() {}); 
		
		model.addAttribute("resServer",resServer);
		model.addAttribute("resType",resType);
		
		//初始化pageNow
				if(pageNow == null||pageNow<1){
					pageNow=1;
				}
		//得到此资源服务器下的client
		final ClientPage clientPage;
		clientPage=webResource.path(id).path("client").path("page").path((pageNow-1)+"").header("Authorization", authorizationBearer(ACCESS_TOKEN)).get(new GenericType<ClientPage>() {});
		
		List<Client> clients = clientPage.getClientList();
		model.addAttribute("clientApps",clients);
		model.addAttribute("totalPage",clientPage.getTotalPage());
		model.addAttribute("totalNum",clientPage.getTotal());
		model.addAttribute("pageNow",pageNow);
		
		String userType = getUserType(request);
		if(USERTYPE_ADMIN.equals(userType)){
			return "resserverview";
		}
		else if(USERTYPE_DEV.equals(userType)){
			return "developer/resserverview";
		}else
			return "error/loginmsg";
	}
	
	

	/**
	 * add one client
	 * @param client
	 * @param resourceServerId
	 * @param attributeName
	 * @param attributeValue
	 * @return
	 */
	@RequestMapping("/client/clientAdd")
	public String clientAdd(@ModelAttribute Client client,String resourceServerId,String[] attributeName,String[] attributeValue,HttpServletRequest request,Integer resType){
		if(!isEmpty(client)){
			WebResource  webResource = com.sun.jersey.api.client.Client.create(config).resource(baseUrl()).path("admin").path("resourceServer");
			//remove all the '' from scopes of client
			Collection<String> nuCon = new Vector<String>();
			nuCon.add(""); 
			List<String> scopeList = client.getScopes();
			if(scopeList!=null && scopeList.size()>0){
				scopeList.removeAll(nuCon);
			}
			client.setScopes(scopeList);
			Map<String, String> attributes = new HashMap<String, String>();
			for(int i=0;i<attributeName.length;i++){
				if(attributeName[i]!=null&&!"".equals(attributeName[i]))
					attributes.put(attributeName[i], attributeValue[i]);
			}
			client.setAttributes(attributes);
			
			client.setUser_id((Integer)request.getSession().getAttribute("userId"));
			webResource.path(resourceServerId).path("client").header("Authorization",
					authorizationBearer(ACCESS_TOKEN)).put(client);
			
			String userType = getUserType(request);
			if(USERTYPE_DEV.equals(userType)){
				long roundom = System.currentTimeMillis();
				return "redirect:../../common/resServer/getOneResServer?id="+resourceServerId+"&resType="+resType+"&rand="+roundom;
			}else if(USERTYPE_ADMIN.equals(userType)){
				long roundom = System.currentTimeMillis();
				return "redirect:../../res/client/getAllClientsPageable?resServerId="+resourceServerId+"&rand="+roundom;
			}else{
				return "error/loginmsg";
			}
		}else{
			System.err.println("注册客户端有字段为空！");
			return "error/error";
		}
	}

	
	@RequestMapping("/client/updateOneClient")
	public String updateOneClient(@ModelAttribute Client client,String resourceServerId,String[] attributeName,String[] attributeValue,HttpServletRequest request){
		WebResource webResource =  com.sun.jersey.api.client.Client.create(config).resource(baseUrl()).path("admin").path("resourceServer");
		//remove the '' from scopes of resServer
		Collection<String> nuCon = new Vector<String>();
		nuCon.add(""); 
		List<String> RedirectUris = client.getRedirectUris();
		RedirectUris.removeAll(nuCon);
		client.setRedirectUris(RedirectUris);
		
		Map<String, String> attributes = new HashMap<String, String>();
		
		for(int i=0;i<attributeName.length;i++){
			if(attributeName[i]!=null&&!"".equals(attributeName[i]))
				attributes.put(attributeName[i], attributeValue[i]);
		}
		client.setAttributes(attributes);
		//根据不用的用户角色（admin or developer）跳转到不同页面
		String userType = getUserType(request);
		if(USERTYPE_ADMIN.equals(userType)){
			webResource.path(resourceServerId).path("client").path(String.valueOf(client.getId())).header("Authorization", authorizationBearer(ACCESS_TOKEN)).post(
					client); 
			
			return "redirect:../../res/client/getAllClientsPageable?resServerId="+resourceServerId;
		}
		else if(USERTYPE_DEV.equals(userType)){
			client.setUser_id((Integer)request.getSession().getAttribute("userId"));
			webResource.path(resourceServerId).path("client").path(String.valueOf(client.getId())).header("Authorization", authorizationBearer(ACCESS_TOKEN)).post(
					client); 
			
			return "redirect:../../getMyClientsPageable";
		}else
			return "error/loginmsg";
		
	}
	
	/**
	 * delete clients
	 * @param Ids
	 * @return
	 */
	@RequestMapping("/client/delClients")
	public String deleteClients(String[] Ids,String resServerId,HttpServletRequest request){
		WebResource  webResource = com.sun.jersey.api.client.Client.create(config).resource(baseUrl()).path("admin").path("resourceServer");
		
		for(int i =0;i<Ids.length;i++){
			Client client = webResource.path(resServerId).path("client").path(Ids[i]).header("Authorization",
					authorizationBearer(ACCESS_TOKEN)).get(new GenericType<Client>(){});
//			Client client = new Client();
			client.setDelete(true);
			webResource.path(resServerId).path("client").path(Ids[i]).header("Authorization",
					authorizationBearer(ACCESS_TOKEN)).post(client);
		}
		String userType = getUserType(request);
		if(USERTYPE_ADMIN.equals(userType)){
			return "redirect:../../res/client/getAllClientsPageable?resServerId="+resServerId+"&rand="+System.currentTimeMillis();
		}else if(USERTYPE_DEV.equals(userType)){
			return "redirect:../../getMyClientsPageable?rand="+System.currentTimeMillis();
		}else
			return "error/loginmsg";
	}
	
	/**
	 * get one client's info
	 * @param model
	 * @param clientId
	 * @param resServerId
	 * @param resServerName
	 * @param flag   which we want to do?view the info or update the info
	 * @return
	 */
	
	@RequestMapping("/client/getOneClient")
	public String getOneClient(ModelMap model,String clientId,String resServerId,String resServerName,String flag,HttpServletRequest request){
		
		WebResource webResource = com.sun.jersey.api.client.Client.create(config).resource(baseUrl()).path("admin").path("resourceServer");
		
		Client client = webResource.path(resServerId).path("client").path(clientId).header("Authorization", authorizationBearer(ACCESS_TOKEN)).get(
				new GenericType<Client>() {}); 
		HttpSession session = request.getSession();
		int userid =(Integer)session.getAttribute("userId");
		String usertype = (String)session.getAttribute("userType");
		//如果是开发者，则只能看自己的client  ,如果是admin则可以看所有的client
		if(USERTYPE_DEV.equals(usertype)){
			if(userid==client.getUser_id()){
				model.addAttribute("client",client);
				if(flag==null||"".equals(flag)){
					model.addAttribute("resourceServerName",resServerName);
					model.addAttribute("resServerId",resServerId);
					return "clientview";
				}else{
					final ResourceServer resourceServer = webResource.path(resServerId).header("Authorization", authorizationBearer(ACCESS_TOKEN)).get(
							new GenericType<ResourceServer>() {}); 
					model.addAttribute("resServer",resourceServer);
					model.addAttribute("resServerId",resServerId);
					return "clientupdate";
				}
			}else{
				return "redirect:../../user/jumpMain";
			}
		}else if(USERTYPE_ADMIN.equals(usertype)){
			model.addAttribute("client",client);
			if(flag==null||"".equals(flag)){
				model.addAttribute("resourceServerName",resServerName);
				model.addAttribute("resServerId",resServerId);
				return "clientview";
			}else{
				final ResourceServer resourceServer = webResource.path(resServerId).header("Authorization", authorizationBearer(ACCESS_TOKEN)).get(
						new GenericType<ResourceServer>() {}); 
				model.addAttribute("resServer",resourceServer);
				model.addAttribute("resServerId",resServerId);
				return "clientupdate";
			}
		}else{
			return "error/loginmsg";
		}
	}
	protected String baseUrl() {
		return String.format("http://localhost:%s/apis-oauth2-server", System.getProperty("servlet.port", String.valueOf(defaultServletPort)));
	}

	// http://localhost:%s/apis-oauth2-server/admin/
	
	protected String baseUrlWith(String suffix) {
		return baseUrl().concat(suffix);
	}

	public static String authorizationBasic(String username, String password) {
		String concatted = username + ":" + password;
		return "Basic " + new String(Base64.encodeBase64(concatted.getBytes()));
	}

	public static String authorizationBearer(String token) {
		return "bearer " + token;
	}
	protected String getUserType(HttpServletRequest request){
		String userType = (String)request.getSession().getAttribute("userType");
		return userType;
	}
	public static boolean isEmpty(Client client){
		if(client==null) return true;
		if(client.getName()==null || "".equals(client.getName().trim())) return true;
		if(client.getDescription()==null || "".equals(client.getDescription().trim())) return true;
//		if(client.getScopes()==null ) return true;
		if(client.getContactName()==null || "".equals(client.getContactName().trim())) return true;
		if(client.getContactEmail()==null || "".equals(client.getContactEmail().trim())) return true;
		if(client.getRedirectUris()==null || client.getRedirectUris().size()==0) return true;
		if(client.isUseRefreshTokens()){
			if(client.getExpireDuration()==0){
				return true;
			}
		}
		return false;
	}

}
